#ifndef __IFACES_CORE_H__
#define __IFACES_CORE_H__

#include "typedefs.h"

#define BOSS_DECLARE_IFACE_UUID(iface_uuid) \
  static Boss::TGuid GetInterfaceId() \
  { \
    return #iface_uuid; \
  }


#define BOSS_UUID_OF(iface) \
  iface::GetInterfaceId()

#ifdef _WIN32
  #ifdef _MSC_VER
    #define BOSS_CALL_TYPE __stdcall 
  #elif defined(__GNUC__)
    #define BOSS_CALL_TYPE __attribute__((stdcall)) 
  #endif
#else
  #ifdef _OS_NIX
    #define BOSS_CALL_TYPE __attribute__((stdcall)) 
  #else
    #error Unsupported OS
  #endif
#endif

namespace Boss
{

  enum RetCode
  {
    rcOk,
    rcFalse,
    rcFail,
    rcBadParam,
    rcNoInterface,
    rcNotImplemented
  };

  struct IBase
  {
    BOSS_DECLARE_IFACE_UUID(00ad47b6-96b2-4570-b5ae-57fbdb019104)

    virtual ULong BOSS_CALL_TYPE AddRef() = 0;
    virtual ULong BOSS_CALL_TYPE Release() = 0;
    virtual TResult BOSS_CALL_TYPE QueryInterface(TGuid ifaceId, TPtr *iface) = 0;
  };

  struct IEnum
    : public IBase
  {
    BOSS_DECLARE_IFACE_UUID(327f4f3c-f36d-4168-940d-f690cbb6c65c)

    virtual TResult BOSS_CALL_TYPE First() = 0;
    virtual TResult BOSS_CALL_TYPE Next(IBase **item) = 0;
    virtual TResult BOSS_CALL_TYPE Clone(IEnum **newEnum) const = 0;
  };

  struct IVariant
    : public IBase
  {
    BOSS_DECLARE_IFACE_UUID(c6f1880a-d666-453c-ae5c-f3c5c30ff526)

    enum VariantType
    {
      vtUnknown,
      vtBool,
      vtBinary,
      vtIBase,
      vtChar,
      vtUChar,
      vtShort,
      vtUShort,
      vtInt,
      vtUInt,
      vtLong,
      vtULong,
      vtFloat,
      vtDouble,
      vtString,
      vtWString
    };

    virtual TResult BOSS_CALL_TYPE SetValue(VariantType type, const TPtr value) = 0;
    virtual TResult BOSS_CALL_TYPE SetBinaryValue(const TPtr value, ULong bytes) = 0;
    virtual TResult BOSS_CALL_TYPE GetValue(TPtr *value) const = 0;
    virtual TResult BOSS_CALL_TYPE GetValueSize(ULong *size) const = 0;
    virtual TResult BOSS_CALL_TYPE IsEmpty(bool *isEmpty) const = 0;
    virtual TResult BOSS_CALL_TYPE GetType(VariantType *type) const = 0;
    virtual TResult BOSS_CALL_TYPE Clear() = 0;	
  };  

}

#endif  // !__IFACES_CORE_H__
